popover: Implement keyboard focus behavior
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 9 Jan 2014 11:53:29 +0000 (12:53 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Wed, 22 Jan 2014 16:10:06 +0000 (17:10 +0100)
When a popover is focused, the focus is forwarded so the first
child what would get the focus actually gets it. Also, implement
correct focus chain, so the keyboard focus stays within the popover
when navigating with keyboard.

gtk/gtkpopover.c

index e68e98362f79db628b394fc93d05969d310b027e..55a2274da1d639d7af7bbab02aa497315502c7fb 100644 (file)
@@ -772,6 +772,46 @@ gtk_popover_key_press (GtkWidget   *widget,
   return GDK_EVENT_PROPAGATE;
 }
 
+static void
+gtk_popover_grab_focus (GtkWidget *widget)
+{
+  /* Focus the first natural child */
+  gtk_widget_child_focus (gtk_bin_get_child (GTK_BIN (widget)),
+                          GTK_DIR_TAB_FORWARD);
+}
+
+static gboolean
+gtk_popover_focus (GtkWidget        *widget,
+                   GtkDirectionType  direction)
+{
+  GtkPopoverPrivate *priv;
+
+  priv = gtk_popover_get_instance_private (GTK_POPOVER (widget));
+
+  if (!GTK_WIDGET_CLASS (gtk_popover_parent_class)->focus (widget, direction))
+    {
+      GtkWidget *focus;
+
+      focus = gtk_window_get_focus (priv->window);
+      focus = gtk_widget_get_parent (focus);
+
+      /* Unset focus child through children, so it is next stepped from
+       * scratch.
+       */
+      while (focus && focus != widget)
+        {
+          gtk_container_set_focus_child (GTK_CONTAINER (focus), NULL);
+          focus = gtk_widget_get_parent (focus);
+        }
+
+      return gtk_widget_child_focus (gtk_bin_get_child (GTK_BIN (widget)),
+                                     direction);
+    }
+
+  return TRUE;
+}
+
+
 static void
 gtk_popover_class_init (GtkPopoverClass *klass)
 {
@@ -792,6 +832,8 @@ gtk_popover_class_init (GtkPopoverClass *klass)
   widget_class->draw = gtk_popover_draw;
   widget_class->button_press_event = gtk_popover_button_press;
   widget_class->key_press_event = gtk_popover_key_press;
+  widget_class->grab_focus = gtk_popover_grab_focus;
+  widget_class->focus = gtk_popover_focus;
 
   /**
    * GtkPopover:relative-to: